package com.clk.portfoy.classlib.portfoy;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import com.clk.portfoy.PortfoyStatics;
import com.clk.portfoy.engines.WebEngine;

public class Portfoy implements InfDeger {

	private List<InfPortfoyObserver> observer = new ArrayList<InfPortfoyObserver>();
	private List<AbsDeger> degerler = new ArrayList<AbsDeger>();
	private HashMap<String, ArrayList<DHisseSenedi>> senetler = new HashMap<String, ArrayList<DHisseSenedi>>();
	private Date refreshDate;

	private double oncekiDeger = -1;

	// ---------------------------------------------------------------------------------
	public Date getRefreshDate() {
		return refreshDate;
	}

	// ---------------------------------------------------------------------------------
	public void register(InfPortfoyObserver obs) {
		if (!observer.contains(obs)) {
			observer.add(obs);
		}
	}

	// ---------------------------------------------------------------------------------
	public void unRegister(InfPortfoyObserver obs) {
		observer.remove(obs);
	}

	// ---------------------------------------------------------------------------------
	private void notifyObs() {
		for (int i = 0; i < observer.size(); i++) {
			observer.get(i).notifyObs(this);
		}
	}

	// ---------------------------------------------------------------------------------
	public boolean contains(AbsDeger deger) {
		for (AbsDeger currentdeger : degerler) {
			if (currentdeger.getIsim().equals(deger.getIsim())) {
				return true;
			}
		}
		return false;
	}

	// ---------------------------------------------------------------------------------
	public void add(AbsDeger deger) {
		if (!this.contains(deger)) {
			if (deger instanceof DHisseSenedi) {
				String letter = deger.getIsim().substring(0, 1);
				ArrayList<DHisseSenedi> liste = senetler.get(letter);
				if (liste == null) {
					liste = new ArrayList<DHisseSenedi>();
					senetler.put(letter, liste);
				}
				liste.add((DHisseSenedi) deger);
			}
			deger.setPortfoy(this);
			degerler.add(deger);
		}
	}

	// ---------------------------------------------------------------------------------
	public void remove(AbsDeger deger) {
		if (this.contains(deger)) {
			if (deger instanceof DHisseSenedi) {
				String letter = deger.getIsim().substring(0, 1);
				ArrayList<DHisseSenedi> liste = senetler.get(letter);
				// liste null olmamali
				if (liste.size() == 1) {
					senetler.remove(letter);
				} else {
					liste.remove(deger);
				}
			}
			degerler.remove(deger);
		}
	}

	// ---------------------------------------------------------------------------------
	public List<AbsDeger> getDegerler() {
		return degerler;
	}

	// ---------------------------------------------------------------------------------
	public double getAlisDeger() {
		// TODO Auto-generated method stub
		double portfoyAlisDeger = 0;
		for (AbsDeger deger : degerler) {
			if (!deger.isRealized()) {
				portfoyAlisDeger += deger.getAdet() * deger.getAlisDeger();
			}
		}
		return portfoyAlisDeger;
	}

	// ---------------------------------------------------------------------------------
	public double getAnlikDeger() {
		// TODO Auto-generated method stub
		double anlikDeger = 0;
		this.oncekiDeger = 0;
		for (AbsDeger deger : degerler) {
			double[] anlikSet = deger.getAnlikDegerSet();
			if (!deger.isRealized()) {
				anlikDeger += anlikSet[0] * deger.getAdet();
				this.oncekiDeger += anlikSet[1] * deger.getAdet();
			}
		}
		return anlikDeger;
	}

	// ---------------------------------------------------------------------------------
	public double getHedefDeger() {
		// TODO Auto-generated method stub
		double hedefDeger = 0;
		for (AbsDeger deger : degerler) {
			if (!deger.isRealized()) {
				hedefDeger += deger.getTotHedefDeger();
			}
		}
		return hedefDeger;
	}

	// ---------------------------------------------------------------------------------
	public double getRealizeDeger() {
		// TODO Auto-generated method stub
		double satisDeger = 0;
		for (AbsDeger deger : degerler) {
			satisDeger += deger.getRealizeDeger() * deger.getAdet();
		}
		return satisDeger;
	}

	// ---------------------------------------------------------------------------------
	public double getPotKZ() {
		// TODO Auto-generated method stub
		double potKZ = 0;
		for (AbsDeger deger : degerler) {
			if (!deger.isRealized()) {
				potKZ += deger.getPotKZ();
			}
		}
		return potKZ;
	}

	// ---------------------------------------------------------------------------------
	public double getPercKZ() {
		// TODO Auto-generated method stub
		double alisDegerler = 0;
		double potKarlar = 0;
		for (AbsDeger deger : degerler) {
			if (!deger.isRealized()) {
				alisDegerler += deger.getAlisDeger() * deger.getAdet();
				potKarlar += deger.getPotKZ();
			}
		}
		return 100 * potKarlar / alisDegerler;
	}

	// ---------------------------------------------------------------------------------
	public double getHedefPotKZ() {
		// TODO Auto-generated method stub
		double hedefPotKZ = 0;
		for (AbsDeger deger : degerler) {
			if (!deger.isRealized()) {
				hedefPotKZ += deger.getHedefPotKZ();
			}
		}
		return hedefPotKZ;
	}

	// ---------------------------------------------------------------------------------
	public double getHedefPercKZ() {
		// TODO Auto-generated method stub
		double alisDegerler = 0;
		double hedefPotKarlar = 0;
		for (AbsDeger deger : degerler) {
			if (!deger.isRealized()) {
				alisDegerler += deger.getAlisDeger() * deger.getAdet();
				hedefPotKarlar += deger.getHedefPotKZ();
			}
		}
		return 100 * hedefPotKarlar / alisDegerler;
	}

	// ---------------------------------------------------------------------------------
	public double getVsVadeliPotKZ() {
		// TODO Auto-generated method stub
		double vsVadeliPotKarlar = 0;
		for (AbsDeger deger : degerler) {
			vsVadeliPotKarlar += deger.getVsVadeliPotKZ();
		}
		return vsVadeliPotKarlar;
	}

	// ---------------------------------------------------------------------------------
	public double getVsVadeliPercKZ() {
		// TODO Auto-generated method stub
		double alisDegerler = 0;
		double vsVadeliPercKarlar = 0;
		for (AbsDeger deger : degerler) {
			alisDegerler += deger.getAlisDeger() * deger.getAdet();
			vsVadeliPercKarlar += deger.getVsVadeliPotKZ();
		}
		return 100 * vsVadeliPercKarlar / alisDegerler;
	}

	// ---------------------------------------------------------------------------------
	public double getRealizeKZ() {
		// TODO Auto-generated method stub
		double realizeDegerler = 0;
		for (AbsDeger deger : degerler) {
			if (deger.getRealizeDeger() != 0) {
				realizeDegerler += (deger.getRealizeDeger() - deger.getAlisDeger()) * deger.getAdet();
			}
		}
		return realizeDegerler;
	}

	// ---------------------------------------------------------------------------------
	public void refresh() {
		try {
			WebEngine.fiilAnlikSenetValues(senetler);
			this.refreshDate = new Date();
			System.out.println("AnlikKZ:" + this.getStrPotKZ());
			System.out.println("***********************************************************************");
			notifyObs();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	// ---------------------------------------------------------------------------------
	// ---------------------------------------------------------------------------------
	public String getStrPotKZ() {
		// TODO Auto-generated method stub
		return PortfoyStatics.getDoubleStr(getPotKZ());
	}

	// ---------------------------------------------------------------------------------
	public String getStrAnlikDeger() {
		// TODO Auto-generated method stub
		return PortfoyStatics.getDoubleStr(getAnlikDeger());
	}

	// ---------------------------------------------------------------------------------
	public String getStrHedefDeger() {
		// TODO Auto-generated method stub
		return PortfoyStatics.getDoubleStr(getHedefDeger());
	}

	// ---------------------------------------------------------------------------------
	public String getStrHedefPotKZ() {
		// TODO Auto-generated method stub
		return PortfoyStatics.getDoubleStr(getHedefPotKZ());
	}

	// ---------------------------------------------------------------------------------
	public String getStrAlisDeger() {
		// TODO Auto-generated method stub
		return PortfoyStatics.getDoubleStr(getAlisDeger());
	}

	// ---------------------------------------------------------------------------------
	public String getStrRealizeDeger() {
		// TODO Auto-generated method stub
		return PortfoyStatics.getDoubleStr(getRealizeDeger());
	}

	// ---------------------------------------------------------------------------------
	public String getStrRealizeKZ() {
		// TODO Auto-generated method stub
		return PortfoyStatics.getDoubleStr(getRealizeKZ());
	}

	// ---------------------------------------------------------------------------------
	public double[] getAnlikDegerSet() {
		double anlikDeger = this.getAnlikDeger();
		if (this.oncekiDeger == -1) {
			this.oncekiDeger = anlikDeger;
		}
		double anlikDegerSet[] = { anlikDeger, this.oncekiDeger };
		return anlikDegerSet;
	}
	// ---------------------------------------------------------------------------------
}
